1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.math;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.math.MathPreconditions.checkNonNegative;
21 import static com.google.common.math.MathPreconditions.checkPositive;
22 import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
23 import static java.lang.Math.min;
24 import static java.math.RoundingMode.HALF_EVEN;
25 import static java.math.RoundingMode.HALF_UP;
26
27 import com.google.common.annotations.GwtCompatible;
28 import com.google.common.annotations.VisibleForTesting;
29
30 import java.math.RoundingMode;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 @GwtCompatible(emulated = true)
47 public final class LongMath {
48
49
50
51
52
53
54
55
56 public static boolean isPowerOfTwo(long x) {
57 return x > 0 & (x & (x - 1)) == 0;
58 }
59
60
61
62
63
64
65 @VisibleForTesting
66 static int lessThanBranchFree(long x, long y) {
67
68 return (int) (~~(x - y) >>> (Long.SIZE - 1));
69 }
70
71
72
73
74
75
76
77
78 @SuppressWarnings("fallthrough")
79
80 public static int log2(long x, RoundingMode mode) {
81 checkPositive("x", x);
82 switch (mode) {
83 case UNNECESSARY:
84 checkRoundingUnnecessary(isPowerOfTwo(x));
85
86 case DOWN:
87 case FLOOR:
88 return (Long.SIZE - 1) - Long.numberOfLeadingZeros(x);
89
90 case UP:
91 case CEILING:
92 return Long.SIZE - Long.numberOfLeadingZeros(x - 1);
93
94 case HALF_DOWN:
95 case HALF_UP:
96 case HALF_EVEN:
97
98 int leadingZeros = Long.numberOfLeadingZeros(x);
99 long cmp = MAX_POWER_OF_SQRT2_UNSIGNED >>> leadingZeros;
100
101 int logFloor = (Long.SIZE - 1) - leadingZeros;
102 return logFloor + lessThanBranchFree(cmp, x);
103
104 default:
105 throw new AssertionError("impossible");
106 }
107 }
108
109
110 @VisibleForTesting static final long MAX_POWER_OF_SQRT2_UNSIGNED = 0xB504F333F9DE6484L;
111
112
113 @VisibleForTesting static final byte[] maxLog10ForLeadingZeros = {
114 19, 18, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12,
115 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4,
116 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0 };
117
118
119
120
121
122
123
124
125
126 public static long gcd(long a, long b) {
127
128
129
130
131
132 checkNonNegative("a", a);
133 checkNonNegative("b", b);
134 if (a == 0) {
135
136
137 return b;
138 } else if (b == 0) {
139 return a;
140 }
141
142
143
144
145 int aTwos = Long.numberOfTrailingZeros(a);
146 a >>= aTwos;
147 int bTwos = Long.numberOfTrailingZeros(b);
148 b >>= bTwos;
149 while (a != b) {
150
151
152
153
154
155
156
157 long delta = a - b;
158
159 long minDeltaOrZero = delta & (delta >> (Long.SIZE - 1));
160
161
162 a = delta - minDeltaOrZero - minDeltaOrZero;
163
164
165 b += minDeltaOrZero;
166 a >>= Long.numberOfTrailingZeros(a);
167 }
168 return a << min(aTwos, bTwos);
169 }
170
171 @VisibleForTesting static final long FLOOR_SQRT_MAX_LONG = 3037000499L;
172
173 static final long[] factorials = {
174 1L,
175 1L,
176 1L * 2,
177 1L * 2 * 3,
178 1L * 2 * 3 * 4,
179 1L * 2 * 3 * 4 * 5,
180 1L * 2 * 3 * 4 * 5 * 6,
181 1L * 2 * 3 * 4 * 5 * 6 * 7,
182 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8,
183 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9,
184 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10,
185 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11,
186 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12,
187 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13,
188 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14,
189 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15,
190 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16,
191 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17,
192 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18,
193 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19,
194 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20
195 };
196
197
198
199
200
201
202
203 public static long binomial(int n, int k) {
204 checkNonNegative("n", n);
205 checkNonNegative("k", k);
206 checkArgument(k <= n, "k (%s) > n (%s)", k, n);
207 if (k > (n >> 1)) {
208 k = n - k;
209 }
210 switch (k) {
211 case 0:
212 return 1;
213 case 1:
214 return n;
215 default:
216 if (n < factorials.length) {
217 return factorials[n] / (factorials[k] * factorials[n - k]);
218 } else if (k >= biggestBinomials.length || n > biggestBinomials[k]) {
219 return Long.MAX_VALUE;
220 } else if (k < biggestSimpleBinomials.length && n <= biggestSimpleBinomials[k]) {
221
222 long result = n--;
223 for (int i = 2; i <= k; n--, i++) {
224 result *= n;
225 result /= i;
226 }
227 return result;
228 } else {
229 int nBits = LongMath.log2(n, RoundingMode.CEILING);
230
231 long result = 1;
232 long numerator = n--;
233 long denominator = 1;
234
235 int numeratorBits = nBits;
236
237
238
239
240
241
242
243 for (int i = 2; i <= k; i++, n--) {
244 if (numeratorBits + nBits < Long.SIZE - 1) {
245
246 numerator *= n;
247 denominator *= i;
248 numeratorBits += nBits;
249 } else {
250
251
252 result = multiplyFraction(result, numerator, denominator);
253 numerator = n;
254 denominator = i;
255 numeratorBits = nBits;
256 }
257 }
258 return multiplyFraction(result, numerator, denominator);
259 }
260 }
261 }
262
263
264
265
266 static long multiplyFraction(long x, long numerator, long denominator) {
267 if (x == 1) {
268 return numerator / denominator;
269 }
270 long commonDivisor = gcd(x, denominator);
271 x /= commonDivisor;
272 denominator /= commonDivisor;
273
274
275 return x * (numerator / denominator);
276 }
277
278
279
280
281
282 static final int[] biggestBinomials =
283 {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 3810779, 121977, 16175, 4337, 1733,
284 887, 534, 361, 265, 206, 169, 143, 125, 111, 101, 94, 88, 83, 79, 76, 74, 72, 70, 69, 68,
285 67, 67, 66, 66, 66, 66};
286
287
288
289
290
291 @VisibleForTesting static final int[] biggestSimpleBinomials =
292 {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 2642246, 86251, 11724, 3218, 1313,
293 684, 419, 287, 214, 169, 139, 119, 105, 95, 87, 81, 76, 73, 70, 68, 66, 64, 63, 62, 62,
294 61, 61, 61};
295
296
297
298 static boolean fitsInInt(long x) {
299 return (int) x == x;
300 }
301
302
303
304
305
306
307
308 public static long mean(long x, long y) {
309
310
311
312 return (x & y) + ((x ^ y) >> 1);
313 }
314
315 private LongMath() {}
316 }